/*
 * MainFrame.cpp
 *
 *  Created on: Aug 25, 2011
 *      Author: erudhes
 */
#include <iostream>
#include <wx/dir.h>
#include "MainFrame.h"
#include "MainPanel.h"
#include "App.h"

// TODO: Refactor this class

BEGIN_EVENT_TABLE(MainFrame, wxFrame)
EVT_MENU(MAIN_FRAME_MENU_NEW_ID_HOST, MainFrame::onMenuNewHostClicked)
EVT_MENU(MAIN_FRAME_MENU_NEW_ID_JOIN, MainFrame::onMenuNewJoinClicked)
EVT_MENU(MAIN_FRAME_MENU_CLOSE_ID, MainFrame::onMenuCloseClicked)
EVT_MENU(MAIN_FRAME_MENU_EXIT_ID, MainFrame::onMenuExitClicked)
END_EVENT_TABLE()

MainFrame::MainFrame(const wxString& title, long style): wxFrame(NULL, MAIN_FRAME_WIN_ID, title, wxDefaultPosition, wxDefaultSize, style),
                                                         mLevels(),
                                                         mMainPanel(NULL)
{
	wxMenu* fileMenu = new wxMenu();
	wxMenu* newSubMenu = new wxMenu();
	wxMenuBar* menuBar = new wxMenuBar();

	newSubMenu->Append(MAIN_FRAME_MENU_NEW_ID_HOST, wxT("Host"));
	newSubMenu->Append(MAIN_FRAME_MENU_NEW_ID_JOIN, wxT("Join"));
	fileMenu->AppendSubMenu(newSubMenu, wxT("New"));
	fileMenu->Append(MAIN_FRAME_MENU_CLOSE_ID, wxT("Close"));
	fileMenu->Append(MAIN_FRAME_MENU_EXIT_ID, wxT("Exit"));
	menuBar->Append(fileMenu, wxT("File"));
	this->SetMenuBar(menuBar);
	mMainPanel = new MainPanel(this);
	this->Center();
}

/*virtual*/
MainFrame::~MainFrame()
{
	// Nothing to do yet
}

void MainFrame::onMenuNewHostClicked(wxCommandEvent& menuEvent)
{
	const unsigned int panelHeight = 80;
	const unsigned int panelWidth = 80;
	const wxString& pathSeparator = wxGetApp().getConfiguration()->getPathSeparator();
	wxString path = wxGetCwd() + pathSeparator + wxGetApp().getConfiguration()->getLevels()->getPath() + pathSeparator;
	wxString title(wxT("Choose a level"));
	wxString level;
	wxDir* levels = new wxDir(path);
	wxDialog* levelDialog = new wxDialog(this, MAIN_FRAME_MENU_NEW_HOST_DIALOG_ID, title);
	wxSize dialogSize;
	bool success = false;
	unsigned int counter = 0;

	if(false == levels->IsOpened())
	{
		this->showErrorMessage(wxT("Could not open file"), true);

		return;
	}
	success = levels->GetFirst(&level, wxEmptyString, wxDIR_DIRS);
	while(true == success)
	{
		wxString bitmapPath = path + level + pathSeparator + wxT("thumbnails.bmp");
		wxBitmap* bitmap = new wxBitmap(bitmapPath, wxBITMAP_TYPE_BMP);
		wxPanel* panel = new wxPanel(levelDialog, (counter % 5) * panelWidth, (counter / 5) * panelHeight, panelWidth, panelHeight);
		/*wxStaticBitmap* staticBitmap = */new wxStaticBitmap(panel, wxID_ANY, *bitmap);
		wxButton* button = new wxButton(panel, MAIN_FRAME_MENU_NEW_HOST_BITMAP_START_ID + counter, wxT("Select"), wxPoint(0, 60), wxSize(panelWidth, 20));

		button->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainFrame::onClicked), NULL, this);
		mLevels.push_back(level);
		counter++;
		success = levels->GetNext(&level);
	}
	if(0 < (counter / 5))
		dialogSize = wxSize(400, ((counter / 5) + 1) * panelHeight);
	else
		dialogSize = wxSize((counter % 5) * panelWidth, panelHeight);
	levelDialog->SetClientSize(dialogSize);
	this->SetClientData(levelDialog);
	levelDialog->Show(true);
}

void MainFrame::onMenuNewJoinClicked(wxCommandEvent& menuEvent)
{
	const unsigned int panelHeight = 40;
	const unsigned int panelWidth = 200;
	wxString title(wxT("Add host name or IP address"));
	wxDialog* hostDialog = new wxDialog(this, MAIN_FRAME_MENU_NEW_JOIN_DIALOG_ID, title);
	wxPanel* panel = new wxPanel(hostDialog, wxID_ANY, wxPoint(0, 0), wxSize(panelWidth, panelHeight));
	/*wxTextCtrl* text = */new wxTextCtrl(panel, MAIN_FRAME_MENU_NEW_JOIN_TEXT_ID, wxString(wxT("127.0.0.1")), wxPoint(0, 0), wxSize(panelWidth, panelHeight / 2));
	wxButton* button = new wxButton(panel, MAIN_FRAME_MENU_NEW_JOIN_BUTTON_ID, wxString(wxT("OK")), wxPoint(0, 20), wxSize(panelWidth, panelHeight / 2));

	button->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainFrame::onClicked), NULL, this);
	hostDialog->SetClientSize(panelWidth, panelHeight);
	this->SetClientData(hostDialog);
	hostDialog->Show(true);
}

void MainFrame::onMenuCloseClicked(wxCommandEvent& menuEvent)
{
	mMainPanel->finish();
}

void MainFrame::onMenuExitClicked(wxCommandEvent& menuEvent)
{
	mMainPanel->finish();
	this->Close(true);
}

void MainFrame::onClicked(wxCommandEvent& commandEvent)
{
	wxWindowBase* eventSource = (wxWindowBase*)commandEvent.GetEventObject();
	wxDialog* dialog = (wxDialog*)this->GetClientData();;

	if(NULL == dialog)
		return;
	this->SetClientData(NULL);
	dialog->Close(true);
	// If we are going to join get the host name, and start the game
	if(MAIN_FRAME_MENU_NEW_JOIN_BUTTON_ID == eventSource->GetId())
	{
		wxTextCtrl* text = NULL;
		const wxWindowList& dialogChildren = dialog->GetChildren();
		const wxWindowList& panelChildren = dialogChildren.GetFirst()->GetData()->GetChildren();

		if(MAIN_FRAME_MENU_NEW_JOIN_TEXT_ID == panelChildren.GetFirst()->GetData()->GetId())
		{
			text = (wxTextCtrl*)panelChildren.GetFirst()->GetData();
			if(false == mMainPanel->joinNew(text->GetValue()))
				this->showErrorMessage(wxT("Error during start procedure"), false);
		}
		else
			this->showErrorMessage(wxT("Error during start procedure"), false);
	}
	else
	{
		wxString level = mLevels[eventSource->GetId() - MAIN_FRAME_MENU_NEW_HOST_BITMAP_START_ID];

		if(false == mMainPanel->hostNew(level))
			this->showErrorMessage(wxT("Error during start procedure"), true);
	}
}

/**
 * PRIVATE METHODS
 */

void MainFrame::showErrorMessage(const wxString& errorMessage, bool hosting)
{
	wxDialog* dialog = NULL;

	if(true == hosting)
		dialog = new wxDialog(this, MAIN_FRAME_MENU_NEW_HOST_ERROR_DIALOG_ID, errorMessage);
	else
		dialog = new wxDialog(this, MAIN_FRAME_MENU_NEW_JOIN_ERROR_DIALOG_ID, errorMessage);

	dialog->Show(true);
}
